/** 
 * 动态布署
 */
import {witch_too_small2} from "/hack_prepare/common-utils.js"
import {get_target_server} from "/hack_prepare/get-target-server.js"

// 应该的占比 目标占比:
  var target_rate_of_grow = 0.877 ;
  var target_rate_of_weaken = 0.112;
  var target_rate_of_hack = 0.011;
// 单次部属的内存的量:
  var deploy_memory_rate = 0.25;

// 显示信息时 进度条长度
const rate_length = 30;
// 把security控制在25%
const target_securate_rate = .25;
// 把money控制在75%
const target_money_rate = .75;
// 控制力度: 
const c_rate_control = 0.00000025;// 2024-06-10 之前是0.00000025 , 在新开一局后, 这样子太慢了. 但是, 服务器的响应本就很慢, 所以有点耐心, 挂着就好.
// 睡眠时间
const c_sleep_time = 20;// 20ms

/**
 * 每小时的比例变化:
 */
function change_pre_hour()
{
  // 一小是3600秒, 也就是3600000ms
  return (3600000/c_sleep_time*c_rate_control).toFixed(3);
}

/**
 * 统一用一个字母指代脚本
 */
const map_script_path = {
  'g': "/hack_prepare/grow-no-loop.js",
  'w': "/hack_prepare/weaken-no-loop.js",
  'h':"/hack_prepare/hack-no-loop.js",
};
const map_script_ram ={
    'g':1.75,
    'w':1.75,
    'h':1.7
}

export async function main(ns) {
  // 1. 取目标服务器
  const str_target_server = await get_target_server(ns);
  const targetServer = str_target_server;

  var count_of_grow_last_time=[0];
  var count_of_weaken_last_time=[0];
  var count_of_hack_last_time=[0];
  var rate_of_grow_last_time=0;
  var rate_of_weaken_last_time=0;
  var rate_of_hack_last_time=0;

  // 目标服务器的信息:
  var max_money = ns.getServerMaxMoney(targetServer);
  var min_security = ns.getServerMinSecurityLevel(targetServer);
  var base_security = ns.getServerBaseSecurityLevel(targetServer)-min_security;

  var name_host = ns.getHostname();
  // ns.tprint("name_host:",name_host);
  // await ns.sleep(100000);
  
  while(true)
  {
    var count_of_grow = 0;
    var count_of_weaken = 0;
    var count_of_hack = 0;
    var rate_of_grow = rate_of_grow_last_time;
    var rate_of_weaken = rate_of_weaken_last_time;
    var rate_of_hack = rate_of_hack_last_time;
    
    var count_of_grow_last_time_sum = count_of_grow_last_time.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
    var count_of_weaken_last_time_sum = count_of_weaken_last_time.reduce((accumulator, currentValue) => accumulator + currentValue, 0);;
    var count_of_hack_last_time_sum = count_of_hack_last_time.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
    
    var home_max_ram = ns.getServerMaxRam(name_host);
    var home_used_ram = ns.getServerUsedRam(name_host);
    var home_remain_ram = home_max_ram - home_used_ram;
    var home_available_ram = home_remain_ram-1000;// 留个1T 给玩家
    var map_count = {'g':0,'w':0,'h':0};//,'e':0

    var ram_use_this_time = home_available_ram*deploy_memory_rate;
    
    // 调整执行的脚本数(粗调)
    if(0<ram_use_this_time)
    {
        ns.print("剩下的内存1:",ns.formatRam(ram_use_this_time));

        // 拿一部分内存粗调
        var a_part_of_ram = ram_use_this_time*.95;
        // ----    g    ----
        var ram_spent_g = map_script_ram['g'];
        let times_g = Math.floor((a_part_of_ram*target_rate_of_grow)/ram_spent_g);
        map_count['g']+=times_g
        // ----    w    ----
        var ram_spent_w = map_script_ram['w'];
        let times_w = Math.floor((a_part_of_ram*target_rate_of_weaken)/ram_spent_w);
        map_count['w']+=times_w;
        // ----    h    ----
        var ram_spent_h = map_script_ram['h'];
        let times_h = Math.floor((a_part_of_ram*target_rate_of_hack)/ram_spent_h);
        map_count['h']+=times_h;
        // ns.print("map_count:",map_count,"\ta_part_of_ram:",a_part_of_ram,"\tram_spent_h:",ram_spent_h);
        // 计算剩下的内存:
        ram_use_this_time -= (times_g*ram_spent_g+times_w*ram_spent_w+times_h*ram_spent_h);
        ns.print("剩下的内存:",ns.formatRam(ram_use_this_time),"\t map_count:",map_count);
        // await ns.sleep(1000);
    }

    // 调整执行的脚本数(微调):
    while(ram_use_this_time>1.75)
    {

      var smaller_one = witch_too_small2(rate_of_grow ,rate_of_weaken ,rate_of_hack,target_rate_of_grow,target_rate_of_weaken,target_rate_of_hack);
        //   var path_of_script = map_script_path[smaller_one];
      var ram_spent = map_script_ram[smaller_one];// ns.getScriptRam(path_of_script);
      ram_use_this_time-=ram_spent;
      ++map_count[smaller_one];
      // 更新数目:
      switch(smaller_one)
      {
      case 'g':++count_of_grow;break;
      case 'w':++count_of_weaken;break;
      case 'h':++count_of_hack;break;
      }
      
      // 更新比例:
      var sum_of_scripts = count_of_grow+count_of_weaken+count_of_hack
        +count_of_grow_last_time_sum+count_of_weaken_last_time_sum+count_of_hack_last_time_sum;
      rate_of_grow = (count_of_grow+count_of_grow_last_time_sum)/sum_of_scripts;
      rate_of_weaken = (count_of_weaken+count_of_weaken_last_time_sum)/sum_of_scripts;
      rate_of_hack = (count_of_hack+count_of_hack_last_time_sum)/sum_of_scripts;
    //   await ns.sleep(1);
    }

    ns.print("剩下的内存:",ns.formatRam(ram_use_this_time),"\t map_count:",map_count);
    var money = ns.getServerMoneyAvailable(targetServer);
    // 在home执行:
    if(map_count['g']>0||map_count['w']>0||map_count['h']>0)
    {
        for(var key in map_count)
        {
            var threads = Math.max(1,map_count[key]);
            if(target_money_rate>money/max_money && 'h' == key) continue;// 解决一直没钱的情况. 
            var script_path = map_script_path[key];
            if(threads)
            {
                ns.exec(script_path,name_host,threads,str_target_server);
            }
        }// END for
    }

    // 在money 过低时, 删除一些正在运行的进程, 使money的水平不会暴降, grow的比例是以现有的money总额为基础的
    if(target_money_rate>money/max_money)
    {
        let list_ps = ns.ps('home');
        // ns.print(list_ps,"\tlist_ps.length:",list_ps.length);
        for(let i=0;i<list_ps.length;++i)
        {
            let process = list_ps[i];
            // ns.print("process:",process);
            // 只杀最近的一个hack进程, 因为可能0.02秒后, 又涨回去了.
            if(process.filename == 'hack_prepare/hack-no-loop.js')
            {
                ns.kill(process.pid,'home');
                ns.print("杀进程:",process.pid,"\t process.filename:",process.filename)
                break;
            }
        }
        // {"filename":"hack_prepare/hack-no-loop.js","threads":2797,"args":["computek"],"pid":584706,"temporary":false}
        // await ns.sleep(10000);
    }

    // BEGIN 记录到[上一次的记录]
    count_of_grow_last_time.push(count_of_grow);
    count_of_weaken_last_time.push(count_of_weaken);
    count_of_hack_last_time.push(count_of_hack);
    if(count_of_grow_last_time.length>100)count_of_grow_last_time.shift();
    if(count_of_weaken_last_time.length>100)count_of_weaken_last_time.shift();
    if(count_of_hack_last_time.length>100)count_of_hack_last_time.shift();
    // END 记录到[上一次的记录]

    // BEGIN 实时显示服务器信息:
    {
    //   var money = ns.getServerMoneyAvailable(targetServer);
      var security_level = await ns.getServerSecurityLevel(targetServer) - min_security;
      var str_rate_money="[";
      for(var i=0;i<rate_length;++i)
      {
        if(money>(max_money/rate_length*i))
        {
          str_rate_money+='■';
        }
        else
        {
          str_rate_money+='-';
        }
      }
      str_rate_money+=']';
      ns.print("money:",(money/max_money*100).toFixed(0),"%\t",str_rate_money);
      var str_rate_security = "[";
      for(var i=0;i<rate_length;++i)
      {
        if( security_level>(base_security/rate_length)*i )
        {
          str_rate_security+='■';
        }
        else
        {
          str_rate_security+='-';
        }
      }
      str_rate_security+=']';
      ns.print("security:\t",str_rate_security);

      // 把security控制在25%
      var security_rate_now = security_level/base_security;
      if(security_rate_now<target_securate_rate)
      {
        // weaken过快时, 慢一点减慢, 过快也是好的.
        target_rate_of_weaken-=(c_rate_control*c_rate_control)*( (target_securate_rate-security_rate_now)/target_securate_rate );
      }
      // if(0==security_rate_now)target_rate_of_weaken-=10*c_rate_control;
      // if(security_rate_now<target_securate_rate)target_rate_of_weaken-=c_rate_control;
      // if(security_rate_now<target_securate_rate*.5)target_rate_of_weaken-=c_rate_control;
      if(security_rate_now>target_securate_rate)
      {
        target_rate_of_weaken+=c_rate_control*((security_rate_now-target_securate_rate)/(1-target_securate_rate));
      }
      // if(security_rate_now>target_securate_rate)target_rate_of_weaken+=c_rate_control;
      // if(security_rate_now>target_securate_rate*2)target_rate_of_weaken+=c_rate_control;
      // if(security_rate_now>target_securate_rate*3)target_rate_of_weaken+=c_rate_control;
      // if(security_rate_now>target_securate_rate*3.5)target_rate_of_weaken+=c_rate_control;
      if(0>target_rate_of_weaken)target_rate_of_weaken=0;
      if(1<target_rate_of_weaken)target_rate_of_weaken=1;
      // 把money控制在75%
      var money_rate_now = money/max_money;
      if(money_rate_now>target_money_rate)
      {
        //target_rate_of_grow-=c_rate_control;
        target_rate_of_grow-=(money_rate_now-target_money_rate)/(target_money_rate*2-target_money_rate)*c_rate_control;
      }
      // if(money_rate_now>Math.sqrt(target_money_rate))target_rate_of_grow-=c_rate_control;
      // if(money_rate_now>.99)target_rate_of_grow-=c_rate_control*10;
      if(money_rate_now<target_money_rate)
      {
        target_rate_of_grow+=(target_money_rate-money_rate_now)/target_money_rate*c_rate_control;
      }
      // if(money_rate_now<target_money_rate*.5)target_rate_of_grow+=c_rate_control;
      // if(money_rate_now<target_money_rate*.25)target_rate_of_grow+=c_rate_control;
      // if(money_rate_now<target_money_rate*.125)target_rate_of_grow+=c_rate_control;
      if(0>target_rate_of_grow)target_rate_of_grow=0;
      if(1<target_rate_of_grow)target_rate_of_grow=1;
      // 调整hack的比例,使三种比例的和为1
      target_rate_of_hack = 1 - target_rate_of_weaken - target_rate_of_grow;
      if(target_rate_of_hack<0)
      {
        target_rate_of_hack = target_rate_of_grow*0.001;
      }

      // BEGIN 显示三种操作的比例:
      {
        var count_of_operation_g = 0;
        var count_of_operation_w = 0;
        var count_of_operation_h = 0;
        var rate_of_operation_g=0,rate_of_operation_w=0,rate_of_operation_h=0;
        for(var i=0;i<rate_length;++i)
        {
          var char_small_one = witch_too_small2(rate_of_operation_g,rate_of_operation_w,rate_of_operation_h
              ,target_rate_of_grow,target_rate_of_weaken,target_rate_of_hack);
          switch(char_small_one)
          {
            case 'g':++count_of_operation_g;break;
            case 'w':++count_of_operation_w;break;
            case 'h':++count_of_operation_h;break;
          }
          // 计算当前的比例
          var sum_operation = count_of_operation_g+count_of_operation_w+count_of_operation_h;
          rate_of_operation_g=count_of_operation_g/sum_operation;
          rate_of_operation_w=count_of_operation_w/sum_operation;
          rate_of_operation_h=count_of_operation_h/sum_operation;
        }// END for
        // 生成图表:
        var str_g = 'g'.repeat(count_of_operation_g);
        var str_w = 'w'.repeat(count_of_operation_w);
        var str_h = 'h'.repeat(count_of_operation_h);
        ns.print("operation:\t","[",str_g,str_w,str_h,"]");
        // ns.print("count_g:",count_of_operation_g,"\tcount_w:",count_of_operation_w,"\tcount_h:",count_of_operation_h);
        ns.print("G.W.H.操作比例:"
            ,target_rate_of_grow.toFixed(3)," , ",target_rate_of_weaken.toFixed(3)," , ",target_rate_of_hack.toFixed(3)
            ,"\t每小时:",change_pre_hour());
      }
      // END   显示三种操作的比例

    }
    // END 实时显示服务器信息

    await ns.sleep(c_sleep_time);
  }
}